//
// Created by Administrator on 2025/8/18.
//

#include "logger.h"

#include "fatfs_task.h"
#include "malloc_ex.h"
#include "usart.h"
#include "semphr.h"
#include "system_api.h"

/**
 * @brief 日志消息队列句柄
 */
QueueHandle_t log_queue=NULL;

/**
 * @brief 日志任务同步信号量
 */
xSemaphoreHandle logger_semaphor=NULL;

/**
 * @brief 备用日志消息队列句柄（用于NTP时间同步前的日志缓存）
 */
QueueHandle_t log_queue_backup=NULL;

/**
 * @brief 日志处理任务
 * 
 * 该任务负责处理系统中的日志信息，包括通过串口输出和存储到文件系统中。
 * 在NTP时间同步之前，日志会暂存在备用队列中；同步完成后，将恢复并处理这些日志，
 * 并且后续日志会加上时间戳后同时输出到串口和保存到文件中。
 * 
 * @param pvParams 任务参数指针（未使用）
 */
void logger_task(void *pvParams)
{
    UNUSED(pvParams);
    //串口缓冲区
    log_queue=xQueueCreate(20,sizeof(char*));
    log_queue_backup=xQueueCreate(20,sizeof(char*));
    logger_semaphor=xSemaphoreCreateBinary();
    // xSemaphoreGive(logger_semaphor);
    if (log_queue==NULL)
    {
        HAL_GPIO_WritePin(GPIOF,GPIO_PIN_10,GPIO_PIN_RESET);
        assert(log_queue);
    }
    char *log_wait_for_print=NULL;
    char *log_backup_wait_for_print=NULL;
    static struct tm time_now;
    bool is_log_recover=false;
    static char fatfs_log_path[96];
    static char *printfBuf=NULL;
    if (printfBuf==NULL)
        printfBuf=(char *)mymalloc(SRAMEX,256);

    for (;;)
    {
        if (xQueueReceive(log_queue,&log_wait_for_print,portMAX_DELAY)==pdTRUE)
        {
            // 通过DMA方式发送日志到串口1
            HAL_UART_Transmit_DMA(&huart1,(uint8_t *)log_wait_for_print,strlen(log_wait_for_print));
            xSemaphoreTake(logger_semaphor,portMAX_DELAY);
            
            // 判断是否已完成日志恢复（即NTP时间同步）
            if (is_log_recover!=true)
            {
                // 如果尚未完成NTP时间同步
                if (sys_get_ntp_status()!=true)
                {
                    char *tmpstr=pvPortMalloc(sizeof(char)*256);
                    snprintf(tmpstr,256,"[Waiting for NTP]->%s",log_wait_for_print);
                    xQueueSend(log_queue_backup,&tmpstr,portMAX_DELAY);
                }
                else
                {
                    // 已获取到NTP时间，处理备份队列中的日志
                    sys_get_time(&time_now);
                    snprintf(fatfs_log_path,sizeof(fatfs_log_path),"1:%04d-%02d-%02d.log",time_now.tm_year+1900,time_now.tm_mon+1,time_now.tm_mday);
                    while (xQueueReceive(log_queue_backup,&log_backup_wait_for_print,0))
                    {
                        fatfs_write_str_to_storage(fatfs_log_path,log_backup_wait_for_print);
                        vPortFree(log_backup_wait_for_print);
                        log_backup_wait_for_print=NULL;
                    }
                    vQueueDelete(log_queue_backup);
                    is_log_recover=true;
                }
            }
            else
            {
                // 正常处理日志：添加时间戳并写入文件系统
                sys_get_time(&time_now);
                snprintf(fatfs_log_path,sizeof(fatfs_log_path),"1:%04d-%02d-%02d.log",time_now.tm_year+1900,time_now.tm_mon+1,time_now.tm_mday);
                snprintf(printfBuf,256,"[%04d-%02d-%02d %02d:%02d:%02d]->%s",time_now.tm_year+1900,time_now.tm_mon+1,time_now.tm_mday,time_now.tm_hour,time_now.tm_min,time_now.tm_sec,log_wait_for_print);
                fatfs_write_str_to_storage(fatfs_log_path,printfBuf);
            }
            vPortFree(log_wait_for_print);
            log_wait_for_print=NULL;
        }
    }

}